#include "test.h"
#include <memory>

class A
{
public:
    A()
    {
        LOG_DEBUG("A()  =====");
    }

    ~A()
    {
        LOG_DEBUG("~A()  =====");
    }

private:
    int m_data {0};
};

class B
{
private:
    B()  = default;
    ~B() = default;
};

class C
{
public:
    C()  = delete;
    ~C() = delete;
};

class E
{
public:
    ~E() = default;

private:
    E() = default;
};

class F
{
public:
    F() = delete;
};

TEST_CASE("shared_ptr", "[smart_ptr]")

{
    std::shared_ptr<A> sp1;
    REQUIRE(sp1 == nullptr);

    sp1.reset(new A());
    CHECK(sp1 != nullptr);
    REQUIRE(sp1.use_count() == 1);

    std::shared_ptr<A> sp2 = sp1;
    REQUIRE(sp1.use_count() == 2);

    sp2.reset();
    REQUIRE(sp2 == nullptr);

    REQUIRE(sp1.use_count() == 1);

    auto sp3 = std::make_shared<A>();
    auto sp4 = sp3;
    REQUIRE(sp3.use_count() == 2);

    sp4.swap(sp1);
    REQUIRE(sp4.use_count() == 1);
    REQUIRE(sp1.use_count() == 2);

    // auto spB = std::make_shared<B>(); // error:: private ~B()
    // auto spC = std::make_shared<C>(); // error:: ~C() = delete

    // auto spE = std::make_shared<E>();
    /*
    error: ‘constexpr E::E()’ is private within this context
           { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    */
    // auto spF = std::make_shared<F>();
    /*
    error: deleted function ‘F::F()’{ ::new((void *)__p)_Up(std::forward<_Args>(__args)...);}
    */
}
